<?php

namespace App\Http\Controllers\GuessCode;

use App\App\Services\Web\UserService;
use App\Contracts\Repositories\ActivityRepository as ActivityRepositoryContact;
use App\Contracts\Services\Storage\StorageService;
use App\Entities\Activity;
use App\Events\GuessCodeCreated;
use App\Events\GuessCodeUpdated;
use App\Http\Controllers\Activity\BaseController as BaseActivityController;
use App\Models\CodeRule\CodeRule;
use Illuminate\Container\Container;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;
use Ramsey\Uuid\Uuid;
use App\Entities\ActivityInfo;

class ActivityController extends BaseActivityController
{

    public function show($id)
    {
        if (!Uuid::isValid($id)) {
            return response()->failed('id不合法');
        }
        $activity = $this->activities->findOne($id);
        if (null === $activity) {
            return response()->failed('没有找到资源');
        }

        $storage = Container::getInstance()->make(StorageService::class);

        $translated = [
            'id' => $activity->id,
            'category' => $activity->category,
            'name' => $activity->name,
            'start_time' => $activity->startTime,
            'end_time' => $activity->endTime,
            'limits' => \GuzzleHttp\json_decode($activity->limit),
            'rules' => \GuzzleHttp\json_decode($activity->rule),
            'background_img' => $storage->toHttpUrl($activity->backgroundImg),
            'background_color' => $activity->backgroundColor,
            'list_background_img' => $storage->toHttpUrl($activity->listBackgroundImg),
            'description' => $activity->description,
            'shares' => $this->formatShares($activity->shares),
            'app_url' => $activity->app_url,
        ];
        return response()->success($translated);
    }
    //重写父类update
    public function update(Request $request, $id)
    {
        $this->checkHttpHeaders($request);
        $input = $request->json()->all();
        $activity = Activity::query()->where('id',$id)->first();
        if(null == $activity){
            return response()->failed("没有找到此活动，或者该活动已被删除");
        }
        $code_rule = $this->getCodeRulesForCreate($request,$id);
        if($code_rule['code'] == 10000){
            return response()->failed($code_rule['message']);
        }
        $validator = Validator::make($input,$this->getRulesForUpdate());
        if($validator->fails()){
            return response()->failed(Arr::first($validator->errors()->all()));
        }
        $input = $this->translateInputFromRequest($request);
        // 去掉不可修改的值
        Arr::forget($input, ['user_id', 'group_code', 'model_id', 'template_id']);
        $activity->fill($input);
        $database  = Container::getInstance()->make('db');
        $success = $database->transaction(function() use ($activity){
            $activity->save();
            $info = ActivityInfo::query()->find($activity->getAttribute('id'));
            if (!$info) {
                return true;
            }

            $info->setAttribute('name', $activity->getAttribute('name'));
            return $info->save();
        });
        if ($success) {
            $code = $this->codeRulesSave($code_rule['data']);
            if($code['code'] == 10000){
                return response()->failed("其他信息保存成功,但是口令规保存失败");
            }
            $this->updatedEvents($activity);
            return response()->success();
        }
        return response()->failed('活动修改失败');
    }
//    protected function translateInputFromRequest(Request $request)
//    {
//        $raw = $request->json()->all();
//
//        $input = array_filter($raw, function ($value) {
//            return null !== $value;
//        });
//        return array_merge($input, [
//            'isPause' => Arr::get($input, 'is_pause', Activity::PAUSED),
//            'clicks' => 0,
//            'joins' => 0,
//            'winnings' => 0,
//            'startTime' => Arr::get($input, 'start_time'),
//            'endTime' => Arr::get($input, 'end_time'),
//            'limit' => $this->parseLimits($request),
//            'backgroundColor' => Arr::get($input, 'background_color', ''),
//            'shares' => $this->parseShares($request),
//            'backgroundImg' => Arr::get($input, 'background_img', ''),
//            'listBackgroundImg' => Arr::get($input, 'list_background_img', ''),
//            'ruleDescription' => Arr::get($input, 'rule_description', ''),
//            'user_id' => $request->header('user-id'),
//            'group_code' => $request->header('group-code'),
//            'description' => Arr::get($input, 'description', ''),
//            'app_url' => Arr::get($input, 'app_url', ''),
//            'publishing_ways' => Arr::get($input, 'publishing_ways', ''),
//            'customId' => Arr::get($input,'customId',''),
//            'organizer' => Arr::get($input,'organizer',''),
//            'others' => Arr::get($input,'others',''),
//            'remark' => Arr::get($input,'remark',''),
//        ]);
//    }
    protected function parseRules(Request $request)
    {
            $rules = [
                'is_spot' => $request->json('rules.is_spot', false),
                'address' => $request->json('rules.address', ''),
                'longitude' => $request->json('rules.longitude', 0.0),
                'latitude' => $request->json('rules.latitude', 0.0),
                'range' => $request->json('rules.range', 1),
            ];
        return json_encode($rules);
    }

    protected function parseLimits(Request $request)
    {
        $limits = [
            'type' => $request->json('limits.type', Activity::LIMIT_DAY),
            'num' => $request->json('limits.num', 1),
        ];
        return json_encode($limits);
    }
    protected function getRulesForCreate()
    {
        return [
            'name' => 'required|max:255',
            'category' => 'required|in:1,2',
            'start_time' => 'required|date',
            'end_time' => 'required|date|after:start_time',
            'model_id' => 'required',
            'template_id' => 'required',
            'description' => 'min:1',
            'limits' => 'required|array',
            'limits.type' => 'in:day,all',
            'limits.num' => 'integer',
            'rules' => 'array',
            'rules.is_spot' => 'boolean',
            'rules.address' => 'required_if:rules.is_spot,1',
            'rules.longitude' => 'required_if:rules.is_spot,1|numeric',
            'rules.latitude' => 'required_if:rules.is_spot,1|numeric',
            'rules.range' => 'required_if:rules.is_spot,1|numeric',
            'shares' => 'array',
            'shares.title' => 'required_if:shares.isopen,on',
            'shares.content' => 'required_if:shares.isopen,on',
        ];
    }

    protected function getRulesForUpdate()
    {
        return [
            'name' => 'max:255',
            'category' => 'in:1,2',
            'start_time' => 'date',
            'end_time' => 'date|after:start_time',
            'description' => 'min:1',
            'limits' => 'array',
            'limits.type' => 'in:day,all',
            'limits.num' => 'integer',
            'code_rule' =>'array',
            'shares' => 'array',
            'shares.title' => 'string',
            'shares.content' => 'string',
        ];
    }
    private function getCodeRulesForCreate($request,$id){
        if(is_array($request->code_rule)){
            return ['code'=>10000,'message'=>"口令规则提交参数错误",'data'=>''];
        }
        $code_rule = $request->code_rule;
        if($code_rule == null){
            return ['code'=>10000,'message'=>"请填写口令规则",'data'=>''];
        }
        $code_rule = \GuzzleHttp\json_decode($code_rule);
        $code_return = [];
        foreach ($code_rule as $key=>&$item){
            if($item->code_status == '' || $item->code == '' || $item->prize_id == '' || $item->stock_number == ''){
                return ['code'=>10000,'message'=>"你有口令信息未填写完成,请仔细检查你提交的口令信息",'data'=>''];
            }
            if($item->code_status == 1){
                try{
                    $code_limits =[
                        'type'=>'fixed',
                        'value'=> $item->fixed,
                    ];
                }catch(\Exception $e){
                    return ['code'=>10000,'message'=>"口令规则类型参数非法",'data'=>''];
                }
            }else if($item->code_status == 2){
                try{
                    $code_limits = [
                        'type'=>'time',
                        'value'=>[
                            'start_time'=>$item->start_time,
                            'end_time' => $item->end_time,
                        ],
                    ];
                }catch(\Exception $e){
                    return ['code'=>10000,'message'=>"口令规则开启时间参数非法",'data'=>''];
                }
            }else{
                return ['code'=>10000,'message'=>"口令类型参数非法",'data'=>''];
            }
            $code_return[$key] = [
                'activity_id' => $id,
                'code_status' => $item->code_status,
//                'code_limits' =>$item->code_limits,
                'code_limits' =>$code_limits,
                'code' => $item->code,
                'stock_number' => $item->stock_number,
                'prize_id' => $item->prize_id,
            ];
        }
        return ['code'=>200,'message'=>"请求成功",'data'=>$code_return];
    }
    public function  codeRulesSave($code_rules){
        $database = Container::getInstance()->make('db');
        foreach($code_rules as $key=>$item){
            $code_rule[$key] = new CodeRule();
            $codes[$key] = $item['code'];
            if($item['code_limits']['type'] == 'fixed' && $item['code_limits']['value'] == 2){
                try{
                    $code =csv_read($item['code']);
                    if(isset($code[1])){
                        return ['code'=>10000,'message'=>"口令文件格式不对,,请按照示例文件上传",'data'=>''];
                    }
                    $codes1 = explode("\r",$code[0]);
                    if(count($codes1)>10001){
                        return ['code'=>10000,'message'=>"超出口令条数，口令条数最多为10000条",'data'=>''];
                    }
                    foreach($codes1 as $item1){
                        if(strlen($item1)>10){
                            return ['code'=>10000,'message'=>"每条口令最多允许十个字",'data'=>''];
                        }
                    }
                    $codes[$key]=array_splice($codes1,1);
                }catch(\Exception $e){
                    return ['code'=>10000,'message'=>"口令文件上传失败,请上传csv格式文件",'data'=>''];
                }
            }
            $item['code_limits']=serialize($item['code_limits']);
            $code_rule[$key]->fill($item);
        }
        foreach($code_rule as $kk=>$vv){
            $success = $database->transaction(function () use ($vv) {
                $vv->save();
                $id = $vv->id;
                return $id;
            });
            $code_redis[$kk] = $vv->attributesToArray();
        }
        foreach ($code_redis as $k=>&$v){
            $v['code'] = $codes[$k];
        }
        $this->codeRuleRedisSave($code_redis,$code_redis[0]['activity_id']);
    }
    public function codeRuleRedisSave($code_redis,$act_id){
        $redis = Container::getInstance()->make('redis');
        try{
            $redis->transaction(function($redis) use($code_redis,$act_id){
                foreach($code_redis as $k=>$c){
                    $code_redis_rule[$k] = [
                        'id'=>$c['id'],
                        'activity_id'=>$c['activity_id'],
                        'code_status'=>$c['code_status'],
                        'code_limits'=>unserialize($c['code_limits']),
                        'prize_id'=>$c['prize_id'],
                        'stock_number'=>$c['stock_number'],
                    ];
                    $code_redis_code = [
                        'code' =>$c['code']
                    ];
                    $code_limits= unserialize($c['code_limits']);
                    if($code_limits['type'] == 'fixed' && $code_limits['value']==2){
                        foreach($code_redis_code['code'] as $item){
                            $redis->lpush("code_rule:$act_id:".$c['id'].":code",$item);
                        }
                    }else{
                        $redis->lpush("code_rule:$act_id:".$c['id'].":code",$c['code']);
                    }
                }
                $code_redis_rule = json_encode($code_redis_rule);
                $redis->set("code_rule:$act_id:rule",$code_redis_rule);
            });
            return ['code'=>200,'message'=>'请求成功','data'=>''];
        }catch(\Exception $e){
            return ['code'=>10000,'message'=>'redis存储失败','data'=>''];
        }
    }
    protected function createdEvents(Activity $activity)
    {
        return event(new GuessCodeCreated($activity));
    }

    protected function updatedEvents(Activity $activity)
    {
        return event(new GuessCodeUpdated($activity));
    }
}
